import logging
import logging
import bcrypt
from sqlalchemy import select
from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError
from datetime import datetime, timezone
from .models import User, UserCreate, UserLogin

# 配置日志
logger = logging.getLogger(__name__)

class UserService:
    """用户服务类，包含用户认证和管理的核心业务逻辑"""
    
    @staticmethod
    def hash_password(password: str) -> str:
        """密码加密处理"""
        salt = bcrypt.gensalt()
        return bcrypt.hashpw(password.encode('utf-8'), salt).decode('utf-8')
    
    @staticmethod
    def verify_password(password: str, hashed_password: str) -> bool:
        """验证密码是否正确"""
        return bcrypt.checkpw(password.encode('utf-8'), hashed_password.encode('utf-8'))
    
    @staticmethod
    def _get_user_by_field(db: Session, field_name: str, field_value: str) -> User:
        """通用用户查询方法，根据指定字段查找用户"""
        try:
            stmt = select(User).where(getattr(User, field_name) == field_value)
            return db.execute(stmt).scalar_one_or_none()
        except Exception as e:
            logger.error(f"查询用户失败: {e}")
            return None
    
    @staticmethod
    def create_user(db: Session, user_data: UserCreate) -> User:
        """创建新用户"""
        try:
            # 检查用户名是否已存在
            existing_username = UserService._get_user_by_field(db, 'username', user_data.username)
            if existing_username:
                raise ValueError("用户名已存在")
            
            # 检查邮箱是否已被注册
            existing_email = UserService._get_user_by_field(db, 'email', user_data.email)
            if existing_email:
                raise ValueError("邮箱已被注册")
            
            # 创建新用户并加密密码
            hashed_password = UserService.hash_password(user_data.password)
            db_user = User(
                username=user_data.username,
                email=user_data.email,
                password_hash=hashed_password
            )
            
            db.add(db_user)
            db.commit()
            db.refresh(db_user)
            logger.info(f"用户创建成功: {user_data.username}")
            return db_user
            
        except ValueError:
            raise
        except Exception as e:
            db.rollback()
            logger.error(f"用户创建失败: {e}")
            raise ValueError("用户创建失败，请稍后重试")
    
    @staticmethod
    def authenticate_user(db: Session, login_data: UserLogin) -> User:
        """用户认证，验证用户名和密码"""
        try:
            user = UserService._get_user_by_field(db, 'email', login_data.email)
            
            if not user or not user.is_active:
                return None
            
            if not UserService.verify_password(login_data.password, user.password_hash):
                return None
            
            # 更新最后登录时间
            user.last_login_at = datetime.now(timezone.utc)
            db.commit()
            
            logger.info(f"用户登录成功: {user.username}")
            return user
            
        except Exception as e:
            logger.error(f"用户认证失败: {e}")
            return None
    
    @staticmethod
    def get_user_by_id(db: Session, user_id: int) -> User:
        """根据ID获取用户信息"""
        return UserService._get_user_by_field(db, 'id', user_id)
    
    @staticmethod
    def get_user_by_email(db: Session, email: str) -> User:
        """根据邮箱获取用户信息"""
        return UserService._get_user_by_field(db, 'email', email)
    
    @staticmethod
    def get_user_by_username(db: Session, username: str) -> User:
        """根据用户名获取用户信息"""
        return UserService._get_user_by_field(db, 'username', username)
    
    @staticmethod
    def update_user_avatar(db: Session, user_id: int, avatar_url: str) -> User:
        """更新用户头像"""
        try:
            user = UserService.get_user_by_id(db, user_id)
            if not user:
                raise ValueError("用户不存在")
            
            user.avatar_url = avatar_url
            user.updated_at = datetime.now(timezone.utc)
            db.commit()
            db.refresh(user)
            
            logger.info(f"用户头像更新成功: {user.username}")
            return user
            
        except ValueError:
            raise
        except Exception as e:
            db.rollback()
            logger.error(f"头像更新失败: {e}")
            raise ValueError("头像更新失败，请稍后重试")
    
    @staticmethod
    def deactivate_user(db: Session, user_id: int) -> bool:
        """停用用户账户"""
        try:
            user = UserService.get_user_by_id(db, user_id)
            if not user:
                raise ValueError("用户不存在")
            
            user.is_active = False
            user.updated_at = datetime.now(timezone.utc)
            db.commit()
            
            logger.info(f"用户账户已停用: {user.username}")
            return True
            
        except ValueError:
            raise
        except Exception as e:
            db.rollback()
            logger.error(f"用户停用失败: {e}")
            raise ValueError("用户停用失败，请稍后重试")